package ch.ethz.fcl.metrofont;

import java.io.BufferedReader;
import java.io.FileNotFoundException;
import java.io.FileReader;
import java.io.IOException;
import java.nio.ByteBuffer;
import java.nio.ByteOrder;
import java.nio.IntBuffer;

import org.lwjgl.opengl.GL11;
import org.lwjgl.opengl.GL15;
import org.lwjgl.opengl.GL20;

public class Shaders {
	int vs, fs;
	int shaderprogram;
	int pixelLocation;
	int textureLocation;
	public int moduloLocation;

	IntBuffer valid;

	public Shaders(String name) throws IOException {
		vs = GL20.glCreateShader(GL20.GL_VERTEX_SHADER);
		fs = GL20.glCreateShader(GL20.GL_FRAGMENT_SHADER);

		ByteBuffer bb = ByteBuffer.allocateDirect(8);
		bb.order(ByteOrder.nativeOrder());
		valid = bb.asIntBuffer();

		BufferedReader brvs = null;
		BufferedReader brfs = null;

		String vs_name = "./lib/shader/" + name + ".vs";
		String fs_name = "./lib/shader/" + name + ".fs";
		try {
			brvs = new BufferedReader(new FileReader(vs_name));
			brfs = new BufferedReader(new FileReader(fs_name));
		} catch (FileNotFoundException e) {
			e.printStackTrace();
		}
		String[] vsrc = new String[1];
		vsrc[0] = "";
		String line_vs;
		while ((line_vs = brvs.readLine()) != null) {
			vsrc[0] += line_vs + "\n";
		}

		GL20.glShaderSource(vs, vsrc);

		String[] fsrc = new String[1];
		fsrc[0] = "";
		String line_fs;
		while ((line_fs = brfs.readLine()) != null) {
			fsrc[0] += line_fs + "\n";
		}

		GL20.glShaderSource(fs, fsrc);
		GL20.glCompileShader(vs);
		GL20.glCompileShader(fs);
		shaderprogram = GL20.glCreateProgram();
		GL20.glAttachShader(shaderprogram, vs);
		GL20.glAttachShader(shaderprogram, fs);
		GL20.glLinkProgram(shaderprogram);
		GL20.glValidateProgram(shaderprogram);

		GL20.glGetProgram(shaderprogram, GL20.GL_VALIDATE_STATUS, valid);
		pixelLocation = GL20.glGetUniformLocation(shaderprogram, "pixel");
		textureLocation = GL20.glGetUniformLocation(shaderprogram, "texture");
		moduloLocation = GL20.glGetAttribLocation(shaderprogram, "modulo");

		int status = valid.get();
		if (status == GL11.GL_TRUE)
			System.out.println("Shader valid");
		else if (status == GL11.GL_FALSE)
			System.out.println("Shader invalid");
		if (pixelLocation != -1) {
			System.out.println("Pixel Location Found");
		}
		if (textureLocation != -1) {
			System.out.println("Texture Location Found");
		}
		if (moduloLocation != -1) {
			System.out.println("Modulo Location Found");
		}
	}

	public void attachShader(int width, int height, int moduloId) {
		GL20.glEnableVertexAttribArray(moduloLocation);
		GL20.glUseProgram(shaderprogram);
		GL15.glBindBuffer(GL15.GL_ARRAY_BUFFER, moduloId);
//		GL20.glVertexAttribPointer(moduloLocation, 1, GL11.GL_FLOAT, false, 0,
//				0);
		GL20.glUniform1i(textureLocation, 0);
		GL20.glUniform2f(pixelLocation, 1.0f / width, 1.0f / height);
	}

	public void disattachShader() {
		GL20.glDisableVertexAttribArray(moduloLocation);
		GL20.glUseProgram(0);
	}
}
